﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Shapes;

namespace Xm.CustomDesigner.UI
{
    public class XmLine : Shape
    {
        private XmCanvas? _canvas;

        private readonly PathFigure? _pathFigure;//线条的路径骨架

        private readonly BezierSegment? _bezierSegment;//贝塞尔曲线段

        internal XmNode? SourceNode { get; set; }

        internal XmNode? TargetNode { get; set; }

        protected override Geometry? DefiningGeometry { get; }//定义几何图形的属性

        internal Point? DragStartPoint { get; set; } = null;//拖动点

        internal event EventHandler? Changed;//线条变化事件


        #region DependencyProperty

        /// <summary>
        /// 源nodeId
        /// </summary>
        public string SourceId
        {
            get { return (string)GetValue(SourceIdProperty); }
            set { SetValue(SourceIdProperty, value); }
        }

        public static readonly DependencyProperty SourceIdProperty =
            DependencyProperty.Register(
                "SourceId",
                typeof(string),
                typeof(XmLine),
                new PropertyMetadata(""));

        /// <summary>
        /// 目标nodeId
        /// </summary>
        public string TargetId
        {
            get { return (string)GetValue(TargetIdProperty); }
            set { SetValue(TargetIdProperty, value); }
        }

        public static readonly DependencyProperty TargetIdProperty =
            DependencyProperty.Register(
                "TargetId",
                typeof(string),
                typeof(XmLine),
                new PropertyMetadata(""));

        #endregion


        /// <summary>
        /// 构造函数
        /// </summary>
        public XmLine()
        {
            _pathFigure = new PathFigure();
            _bezierSegment = new BezierSegment();
            _pathFigure.Segments.Add(_bezierSegment);//添加曲线段

            this.DefiningGeometry = new PathGeometry(new PathFigure[] { _pathFigure });//定义路径几何图形

            this.StrokeThickness = 2;
            this.Stroke = Brushes.Black;

            this.Loaded += OnLoaded;

        }

        /// <summary>
        /// 线条创建时触发
        /// </summary>
        private void OnLoaded(object sender, RoutedEventArgs e)
        {
            _canvas = this.FindParent<XmCanvas>();

            if (_canvas != null)
            {
                if (this.SourceNode == null || this.TargetNode == null)
                {
                    var sObj = _canvas.FindName(this.SourceId);
                    var tObj = _canvas.FindName(this.TargetId);


                    if (sObj is XmNode source && tObj is XmNode target)
                    {

                        this.SourceNode = source;
                        this.TargetNode = target;
                    }
                }


                if (this.SourceNode != null && this.TargetNode != null)
                {
                    //建立委托关系，用于监听节点的变化
                    this.SourceNode.Changed += this.OnChanged;
                    this.TargetNode.Changed += this.OnChanged;

                    //初次加载即生效
                    this.OnChanged(this, EventArgs.Empty);
                }
            }
        }

        /// <summary>
        /// 线条变化即绘制曲线
        /// </summary>
        private void OnChanged(object? sender, EventArgs e)
        {
            if (this.SourceNode == null || this.TargetNode == null)
                return;

            var start = this.SourceNode.Right;
            var end = this.TargetNode.Left;

            var p1 = new Point(start.X - 30, start.Y);
            var p2 = new Point(end.X - 30, end.Y);

            if (this.SourceNode.Right.X < this.TargetNode.Left.X)
            {
                start = this.SourceNode.Right;
                end = this.TargetNode.Left;
                p1.X = start.X + 30;
            }
            else if (this.SourceNode.Right.X > this.TargetNode.Left.X)
            {
                start = this.SourceNode.Left;
                end = this.TargetNode.Right;
                p2.X = end.X + 30;
            }

            //(重新)绘制曲线
            _pathFigure.StartPoint = start;
            _bezierSegment.Point1 = p1;
            _bezierSegment.Point2 = p2;
            _bezierSegment.Point3 = end;
        }

    }
}
